package com.efast.cafe.portal.controller.common;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.model.OSSObject;
import com.efast.cafe.framework.bean.FileChunkInfo;
import com.efast.cafe.framework.bean.ResultBean;
import com.efast.cafe.framework.controller.AbstractController;
import com.efast.cafe.framework.enums.ResultStatus;
import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.portal.bean.common.AttachmentBean;
import com.efast.cafe.portal.bean.common.FileUploadReturnBean;
import com.efast.cafe.portal.entity.common.PortalAttachment;
import com.efast.cafe.portal.service.common.IPortalAttachmentService;
import com.efast.cafe.util.AliyunOSSUtil;
import com.efast.cafe.util.ConfigUtil;
import com.efast.cafe.util.FileUploadUtil;
import com.efast.cafe.util.FileUtil;
import com.efast.cafe.util.date.DateUtils;

/******************************************************************************
 * @File name : FileUploadController.java
 * 
 * @Author : fxm
 * 
 * @Date : 2016-11-17
 * 
 * @Copyright Notice: Copyright (c) 2016 Efast Serv. All Rights Reserved. This
 *            software is published under the terms of the Efast Software
 *            License version 1.0, a copy of which has been included with this
 *            distribution in the LICENSE.txt file.
 * 
 * 
 *            ------------------------------------------------------------------
 *            ---------- Date Who Version Comments 2016-11-17 下午12:00:21 fxm 1.0
 *            Initial Version
 *****************************************************************************/
@Controller
public class AttachmentController extends AbstractController{

	@Autowired
	private IPortalAttachmentService portalAttachmentService;
	
	
	/**
	 * 文件上傳
	 * @param file
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/frame_center/common/attachmentUpload")
	public @ResponseBody List<FileUploadReturnBean> upload(
			@RequestParam("files") MultipartFile[] files,
			HttpServletResponse response,
			HttpServletRequest request, ModelMap model) {
		
		String fileSaveType = "1";
		String configSaveType = ConfigUtil.getValue("upload.saveType");
		if(StringUtils.isNotBlank(configSaveType)){
			fileSaveType = configSaveType;
		}
		//fileSaveType 为空或者为1 默认传到指定目录
		//fileSaveType 为2 上传到oss服务器
		String path = ConfigUtil.getUploadDir();
		try{
			List<PortalAttachment> atts = new ArrayList<>();
			for(int i=0;i<files.length;i++){
				MultipartFile uploadFile = files[i];
				String sysFileName = uploadFile.getOriginalFilename();
				PortalAttachment attr = new PortalAttachment();
				if(StringUtils.isBlank(fileSaveType) || fileSaveType.equals("1")){
					sysFileName = FileUtil.saveFile(path, sysFileName, uploadFile);
				}else if(fileSaveType.equals("2")){//oss
					sysFileName = new StringBuffer(sysFileName.substring(0, sysFileName.lastIndexOf(".")))
							.append("-")
							.append(UUID.randomUUID().toString())
							.append(sysFileName.substring(sysFileName.lastIndexOf(".")))
							.toString();
					String accesskeyid = ConfigUtil.getValue("oss.manager.accesskeyid"); 
					String accesskeysecret = ConfigUtil.getValue("oss.manager.accesskeysecret"); 
					String bucket = ConfigUtil.getValue("oss.manager.bucket"); 
					AliyunOSSUtil util = AliyunOSSUtil.getInstance(accesskeyid, accesskeysecret, bucket);
					File f = (File) uploadFile;
					path = "imgs/"+DateUtils.format(new Date())+"/";
					String ossFieldId = util.uploadObject2OSS(f, sysFileName, path);
					attr.setOssFieldId(ossFieldId);
				}
				
				attr.setFileSaveType(fileSaveType);
				attr.setFilePath(path);
				attr.setFileExt(uploadFile.getContentType());
				attr.setIsDelete(0);
				attr.setRealName(uploadFile.getOriginalFilename());
				attr.setSysName(sysFileName);
                attr.setFileSize(new BigDecimal(uploadFile.getSize()).divide(new BigDecimal(1024)).floatValue());
				atts.add(attr);
			}
			
			List<FileUploadReturnBean> attrids = portalAttachmentService.saveAttrachment(atts);
			return attrids;
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 删除附件
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/frame_center/common/attachmentDel")
	public @ResponseBody ResultBean deleteAttr(	@RequestBody Map<String,Integer> map){
		ResultBean result=new ResultBean(true, "");
		
		 Integer id=null;
		 if(map.containsKey("id")){
			id=map.get("id");
		 }
	
		try {
			if(id==null){
				throw new ServiceException(ResultStatus.PARAM_ERROR.getCode());
			}
			if(portalAttachmentService.queryAttachmentById(id)==null){
				throw new ServiceException("数据不存在");
			}
			portalAttachmentService.deleteAttrachment(id);
		} catch (Exception e) {
			result.setSuccess(false);
			if (e instanceof ServiceException) {
				result.setErrorCode(e.getMessage());
			} else {
				result.setErrorCode(ResultStatus.SYS_ERROR.getCode());
			}
		}

		return result;
	}
	
	/**
	 * 获取附件集合
	 * @param formId
	 * @param group
	 * @return
	 */
	@RequestMapping(value = "/frame_center/common/attachmentList")
	public @ResponseBody ResultBean  attachmentList(
			@RequestBody AttachmentBean bean){
		ResultBean result=new ResultBean(true, "");
		try {
		     result.setObject(portalAttachmentService.findAttachList(bean.getFormId(), bean.getGroupId()));
		} catch (Exception e) {
			result.setSuccess(false);
			if (e instanceof ServiceException) {
				result.setErrorCode(e.getMessage());
			} else {
				result.setErrorCode(ResultStatus.SYS_ERROR.getCode());
			}
		}

		return result;
	}

    /**
     * 获取附件集合
     * @param formId
     * @param group
     * @return
     */
    @RequestMapping(value = "/frame_center/common/attachmentListTable")
    public @ResponseBody ResultBean  attachmentListTable(
            @RequestBody AttachmentBean bean){
        ResultBean result=new ResultBean(true, "");
        try {
            result.setObject(portalAttachmentService.attachmentListTable(bean.getFormId(), bean.getGroupId()));
        } catch (Exception e) {
            result.setSuccess(false);
            if (e instanceof ServiceException) {
                result.setErrorCode(e.getMessage());
            } else {
                result.setErrorCode(ResultStatus.SYS_ERROR.getCode());
            }
        }

        return result;
    }
	
	/**
	 * 附件下载
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/frame_center/common/attachmentDownload")
	public ResponseEntity<byte[]> download(@RequestParam Integer attachmentId
			,HttpServletRequest request, HttpServletResponse response) throws IOException{
		PortalAttachment att = portalAttachmentService.queryAttachmentById(attachmentId);
		if(null!=att){
			 HttpHeaders headers = new HttpHeaders();
			 String fileName=new String(att.getRealName().getBytes("UTF-8"),"iso-8859-1");//解决乱码
			 headers.setContentDispositionFormData("attachment", fileName);
			 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); 
			 
			String path = att.getFilePath();
			if(StringUtils.isBlank(att.getFileSaveType()) || "1".equals(att.getFileSaveType())){
				/*File file=new File(path+File.separator+att.getSysName());  
				 return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),    
	                     headers, HttpStatus.CREATED); */
				String url=att.getFilePath()+att.getSysName();
				download(url,response,att.getRealName());
			}else if(att.getFileSaveType().equals("2")){//oss
				String accesskeyid = ConfigUtil.getValue("oss.manager.accesskeyid"); 
				String accesskeysecret = ConfigUtil.getValue("oss.manager.accesskeysecret"); 
				String bucket = ConfigUtil.getValue("oss.manager.bucket"); 
				AliyunOSSUtil util = AliyunOSSUtil.getInstance(accesskeyid, accesskeysecret, bucket);
				OSSObject ossObject = util.getObject(att.getOssFieldId());
				 BufferedInputStream in=new BufferedInputStream(ossObject.getObjectContent()); 
				 return new ResponseEntity<byte[]>(IOUtils.toByteArray(in),    
	                     headers, HttpStatus.CREATED); 
			}
			
		}
		return null;
	}
	
	/**
 	 * 附件下载
 	 * @return
 	 * @throws IOException
 	 */
     public HttpServletResponse download(String path, HttpServletResponse response,String realName) {
    	 try {
    	 // path是指欲下载的文件的路径。
    	 File file = new File(path);
    	 // 取得文件名。
    	 String filename = file.getName();
    	 // 取得文件的后缀名。
    	 String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
    	 // 以流的形式下载文件。
    	 InputStream fis = new BufferedInputStream(new FileInputStream(path));
    	 byte[] buffer = new byte[fis.available()];
    	 fis.read(buffer);
    	 fis.close();
    	 // 清空response
    	 response.reset();
    	 // 设置response的Header
    	 response.addHeader("Content-Disposition", "attachment;filename=" + new String(realName.getBytes("UTF-8"),"ISO8859-1"));
    	 response.addHeader("Content-Length", "" + file.length());
    	 OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
    	 response.setContentType("application/octet-stream");
    	 toClient.write(buffer);
    	 toClient.flush();
    	 toClient.close();
    	 } catch (IOException ex) {
    	 ex.printStackTrace();
    	 }
    	 return response;
    	 }
 	
 	

 	@RequestMapping(value = "/frame_center/common/attachmentChunkUpload")
 	public @ResponseBody ResultBean upload(@RequestParam("files") MultipartFile file, HttpServletResponse response,
 			HttpServletRequest request, FileChunkInfo chunkInfo,@RequestParam(value = "attachmentId",required = false) Integer attachmentId,@RequestParam(value = "fileId",required = false) String fileId) {

 		ResultBean result = new ResultBean(true, "");
 		String rootPath = ConfigUtil.getValue("cafe.upload.tempDir");
 		List<PortalAttachment> atts = new ArrayList<PortalAttachment>();
 		
 		try {
 			if (chunkInfo.getChunkCount() > 1) {
 				// 分片上传
 				File tempFile = FileUploadUtil.getReadySpace(chunkInfo, rootPath);
 				// 分片文件
 				// 将inputStream流写入临时文件片中
 				if (tempFile == null) {
 					result.setSuccess(false);
 					result.setMessage("上传失败");
 					return result;
 				}
 				file.transferTo(tempFile);
 				// 最后一片文件
 				if (chunkInfo.getChunkIndex()!=null&&chunkInfo.getChunkCount()!=null&&
 						chunkInfo.getChunkIndex().equals(chunkInfo.getChunkCount())	) {
 					// 得到文件的所有分片
 					File uploadFile = FileUploadUtil.mergerFile(chunkInfo, rootPath);
 					// 将文件保存到指定服务器中
 					PortalAttachment att = saveFileToService(chunkInfo.getFileName(), uploadFile, file.getContentType());
                    att.setFileSize(new BigDecimal(uploadFile.length()).divide(new BigDecimal(1024)).floatValue());
 					att.setFileId(fileId);
                    att.setId(attachmentId);
                    atts.add(att);
 					// 删除合并的文件
 					FileUtil.deleteDirectory(FileUploadUtil.getChunkFlod(chunkInfo, rootPath));
 				}
 			} else {
 				PortalAttachment att = saveToServiceNoChunk(chunkInfo.getFileName(), file);
                att.setFileSize(new BigDecimal(file.getSize()).divide(new BigDecimal(1024)).floatValue());
                att.setFileId(fileId);
                att.setId(attachmentId);
                atts.add(att);
 			}
 			if (!atts.isEmpty()) {
 				String formId = chunkInfo.getUuid();
 				// 保存文件上传记录
 				List<FileUploadReturnBean> attrids = portalAttachmentService.saveAttrachment(atts);
 				result.setObject(attrids);
 				result.setMessage("保存成功！");
 			}
 		} catch (Exception e) {
 			result.setSuccess(false);
 			e.printStackTrace();
 		}
 		return result;

 	}
 	/**
 	 * 不分片直接上传文件
 	 * 
 	 * @param sysFileName
 	 * @param uploadFile
 	 * @return DocFiles
 	 * @Author Administrator
 	 * @Date 2017年9月21日
 	 */
 	private PortalAttachment saveToServiceNoChunk(String fileName, MultipartFile uploadFile) {
 		String path = ConfigUtil.getUploadDir();
 		String fileSaveType = "1";
 		String configSaveType = ConfigUtil.getValue("upload.saveType");
 		String sysFileName = fileName;
 		if (StringUtils.isNotBlank(configSaveType)) {
 			fileSaveType = configSaveType;
 		}
 		PortalAttachment attr = new PortalAttachment();
 		if (StringUtils.isBlank(fileSaveType) || fileSaveType.equals("1")) {
 			sysFileName = FileUtil.saveFile(path, sysFileName, uploadFile);
 		} else if (fileSaveType.equals("2")) {// oss
 			sysFileName = new StringBuffer(fileName.substring(0, fileName.lastIndexOf("."))).append("-")
 					.append(UUID.randomUUID().toString()).append(fileName.substring(fileName.lastIndexOf(".")))
 					.toString();
 			String accesskeyid = ConfigUtil.getValue("oss.manager.accesskeyid");
 			String accesskeysecret = ConfigUtil.getValue("oss.manager.accesskeysecret");
 			String bucket = ConfigUtil.getValue("oss.manager.bucket");
 			AliyunOSSUtil util = AliyunOSSUtil.getInstance(accesskeyid, accesskeysecret, bucket);
 			File f = (File) uploadFile;
 			path = "imgs/" + DateUtils.format(new Date()) + "/";
 			String ossFieldId = util.uploadObject2OSS(f, sysFileName, path);
 			attr.setOssFieldId(ossFieldId);
 		}

 		attr.setFileSaveType(fileSaveType);
 		attr.setFilePath(path);
 		attr.setFileExt(uploadFile.getContentType());
 		attr.setIsDelete(0);
 		attr.setRealName(fileName);
 		attr.setSysName(sysFileName);
 		return attr;
 	}

 	/**
 	 * 
 	 * @param fileName
 	 * @param sysFileName
 	 * @param atts
 	 * @param file
 	 * @param uploadFile
 	 *            待上传的文件 void
 	 * @Author Administrator
 	 * @Date 2017年9月21日
 	 */
 	private PortalAttachment saveFileToService(String fileName, File uploadFile, String contentType) {
 		if(uploadFile==null){
 			return null;
 		}
 		String sysFileName = null;
 		String fileSaveType = "1";
 		String configSaveType = ConfigUtil.getValue("upload.saveType");
 		if (StringUtils.isNotBlank(configSaveType)) {
 			fileSaveType = configSaveType;
 		}
 		// fileSaveType 为空或者为1 默认传到指定目录, fileSaveType 为2 上传到oss服务器
 		String path = ConfigUtil.getUploadDir();
 		PortalAttachment attr = new PortalAttachment();
 		if (StringUtils.isBlank(fileSaveType) || fileSaveType.equals("1")) {
 			sysFileName = FileUploadUtil.saveFile(path, fileName, uploadFile);
 		} else if (fileSaveType.equals("2")) {// oss
 			sysFileName = new StringBuffer(fileName.substring(0, fileName.lastIndexOf("."))).append("-")
 					.append(UUID.randomUUID().toString()).append(fileName.substring(fileName.lastIndexOf(".")))
 					.toString();
 			String accesskeyid = ConfigUtil.getValue("oss.manager.accesskeyid");
 			String accesskeysecret = ConfigUtil.getValue("oss.manager.accesskeysecret");
 			String bucket = ConfigUtil.getValue("oss.manager.bucket");
 			AliyunOSSUtil util = AliyunOSSUtil.getInstance(accesskeyid, accesskeysecret, bucket);
 			path = "imgs/" + DateUtils.format(new Date()) + "/";
 			String ossFieldId = util.uploadObject2OSS(uploadFile, sysFileName, path);
 			attr.setOssFieldId(ossFieldId);
 		}
 		attr.setFileSaveType(fileSaveType);
 		attr.setFilePath(path);
 		attr.setFileExt(contentType);
 		attr.setIsDelete(0);
 		attr.setRealName(fileName);
 		attr.setSysName(sysFileName);
 		return attr;
 	}


    /**
     * 获取附件集合
     * @param fileId
     * @param realName
     * @param fileComments
     * @param attachmentId
     * @return
     */
    @RequestMapping(value = "/frame_center/common/attachmentEdit")
    public @ResponseBody ResultBean  attachmentEdit(
            @RequestBody AttachmentBean bean){
        ResultBean result=new ResultBean(true, "");
        try {
            portalAttachmentService.attachmentEdit(bean);
        } catch (Exception e) {
            result.setSuccess(false);
            if (e instanceof ServiceException) {
                result.setErrorCode(e.getMessage());
            } else {
                result.setErrorCode(ResultStatus.SYS_ERROR.getCode());
            }
        }

        return result;
    }
}
